home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Documents / NeXTAnswers / appkit.401 < prev    next >
Text File  |  1992-02-06  |  11KB  |  299 lines

  1. {\rtf0\ansi{\fonttbl\f2\fnil Times-Roman;\f3\fmodern Ohlfs;\f1\fmodern Courier;}
  2. \paperw13040
  3. \paperh8160
  4. \margl120
  5. \margr120
  6. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\b0\i0\ul0\fs28 server memory postscript vm NXShowAllWindows ProcessMonitor\
  7. \
  8. Q:  How can I tell how much window server memory my application is using?\
  9. Some Application Kit programs can use a significant number of windows and\
  10. bitmaps, and the memory used in these cases isn't easy to trace.\
  11. \
  12.  
  13. \b For 1.0
  14. \b0 \
  15. A:  Check out the following two files (wsmemory.psw and wsmem.h), which define the interface and source code for a routine called NXWindowServerMemory().  This is a function which returns the amount of PostScript VM and window backing store is used by your application at the time you call it.  These files use published interfaces and are freely distributable.  Developers are encouraged to make these measurements by compiling and linking in this code. \
  16. \
  17. Another way to trace the windows created by an appliction is to run applications with the NXShowAllWindows switch set to YES. (You can either run the application from a Shell to accomplish this or just set the default value with dwrite.)  This switch causes all windows created in the server to be displayed on the screen and makes them non-buffered so you can see all drawing as it happens.\
  18. \
  19. ---wsmem.h---\
  20.  
  21. \f3\fs24 \
  22.  
  23. \f1\b /*\
  24.     Copyright (c) 1990 NeXT, Inc.\
  25.     All Rights Reserved.\
  26. \
  27.     wsmem.h\
  28.     Procedure prototype for NXWindowServerMemory\
  29.     Leovitch 06Jan90\
  30.     \
  31.     Synopsis:\
  32.     \
  33.     int NXWindowServerMemory(DPSContext *context,\
  34.         int *vmUsedP, int *windowBackingP,\
  35.         NXStream *windowDumpStream);\
  36.     \
  37.     NXWindowServerMemory calculates the amount of window\
  38.     server memory being used at the moment by the window\
  39.     server context given as context.  If NULL is passed for\
  40.     the context, the current context is used.  The amount\
  41.     of PostScript VM used by the current context is returned\
  42.     in the int pointed to by vmUsedP; the amount of window\
  43.     backing store used by windows owned by the current\
  44.     context is returned in the int\
  45.     pointed to by windowBackingP.  The sum of these two numbers\
  46.     is the amount of the window server's memory which this\
  47.     PostScript context is responsible for.\
  48.     \
  49.     In order to calculate these numbers, NXWindowServerMemory\
  50.     uses the PostScript operators dumpwindows and vmstatus.\
  51.     NXWindowServerMemory takes a substantial fraction of a \
  52.     second to execute; thus, calling this function\
  53.     in normal operation is not recommended.  It should be used\
  54.     for debugging and performance analysis purposes.\
  55.     \
  56.     If a non-NULL value is passed in for windowDumpStream, then\
  57.     the information returned from the dumpwindows operator\
  58.     is echoed to the NXStream given.  This can be useful for\
  59.     finding out more about which windows are using up your\
  60.     storage.\
  61.     \
  62.     Return Value\
  63.     \
  64.     Normally, NXWindowServerMemory returns 0.  If NULL is passed\
  65.     for context and there is no current DPS Context, -1 is returned.\
  66.     \
  67.     */\
  68. \
  69. int NXWindowServerMemory(DPSContext context,\
  70.         int *vmUsedP, int *windowBackingP,\
  71.         NXStream *windowDumpStream);\
  72.  
  73. \f3\b0 \
  74. \
  75.  
  76. \f2\fs28 ---wsmemory.psw---
  77. \fs24 \
  78. \
  79.  
  80. \f1\b /*\
  81.     Copyright (c) 1990 NeXT, Inc.\
  82.     All Rights Reserved.\
  83.     \
  84.     wsmemory.psw\
  85.     \
  86.     This module defines the function NXWindowServerMemory,\
  87.     which will return the amount of window server memory\
  88.     being used by the current window server context.\
  89. \
  90.     Synopsis:\
  91.     \
  92.     int NXWindowServerMemory(DPSContext *context,\
  93.         int *vmUsedP, int *windowBackingP,\
  94.         NXStream *windowDumpStream);\
  95.     \
  96.     NXWindowServerMemory calculates the amount of window\
  97.     server memory being used at the moment by the window\
  98.     server context given as context.  If NULL is passed for\
  99.     the context, the current context is used.  The amount\
  100.     of PostScript VM used by the current context is returned\
  101.     in the int pointed to by vmUsedP; the amount of window\
  102.     backing store used by windows owned by the current\
  103.     context is returned in the int\
  104.     pointed to by windowBackingP.  The sum of these two numbers\
  105.     is the amount of the window server's memory which this\
  106.     PostScript context is responsible for.\
  107.     \
  108.     In order to calculate these numbers, NXWindowServerMemory\
  109.     uses the PostScript operators dumpwindows and vmstatus.\
  110.     It takes some time to execute; thus, calling this function\
  111.     in normal operation is not recommended.\
  112.     \
  113.     If a non-NULL value is passed in for windowDumpStream, then\
  114.     the information returned from the dumpwindows operator\
  115.     is echoed to the NXStream given.  This can be useful for\
  116.     finding out more about which windows are using up your\
  117.     storage.\
  118.     \
  119.     Return Value\
  120.     \
  121.     Normally, NXWindowServerMemory returns 0.  If NULL is passed\
  122.     for context and there is no current DPS Context, -1 is returned.\
  123.     \
  124.     */\
  125. \
  126. #import <strings.h>\
  127. #import <stdlib.h>\
  128. #import <streams/streams.h>\
  129. #import <dpsclient/dpsclient.h>\
  130. \
  131. /* These three variables define a buffer filled by _NXMyTextProc below,\
  132.    and parsed by the NXWindowServerMemory procedure. */\
  133. static char *responseBuffer; /* Pointer to character buffer */\
  134. static int responseBufCount; /* Number of bytes in buffer currently */\
  135. static int responseBufSize;  /* Total size of buffer */\
  136. #define MINRESPBUFSIZE 500\
  137. \
  138. /* Prototype for _NXMyTextProc; implementation is below NXWindowServerMemory */\
  139. static void _NXMyTextProc(\
  140.     DPSContext context, \
  141.     char *buf, \
  142.     long unsigned int count);\
  143. \
  144. /*\
  145.     _NXvmstatus is a pswrap which calls the vmstatus operator after\
  146.     doing a private VM garbage collection.  You need to do a garbage\
  147.     collection in order to get consistent results from the vmstatus\
  148.     operator.  */\
  149.     \
  150. defineps static _NXvmstatus(DPSContext context|int *vmUsed)\
  151.     % First, make sure we get the status for our private VM\
  152.     currentshared false setshared\
  153.     % Do a private garbage collection\
  154.     1 vmreclaim\
  155.     % OK, get the answer\
  156.     vmstatus pop vmUsed pop\
  157.     % and restore the old shared state\
  158.     setshared\
  159. endps\
  160. \
  161. int NXWindowServerMemory(DPSContext context,\
  162.         int *vmUsedP, int *windowBackingP,\
  163.         NXStream *windowDumpStream)\
  164. \{\
  165.     int bytes,totalBytes;\
  166.     DPSTextProc oldTextProc;\
  167.     char *buf,*bufEnd,*newBuf;\
  168.     \
  169.     /* First, make sure that either there is a current context or we were\
  170.        passed one. */\
  171.     if (context == NULL)\
  172.     \{\
  173.         context = DPSGetCurrentContext();\
  174.     if (context == NULL)\
  175.         return(-1);\
  176.     \}\
  177.     \
  178.     /* Reset the character buffer variables */\
  179.     responseBuffer = NULL;\
  180.     responseBufSize = responseBufCount = 0;\
  181.     \
  182.     /* We'll get the PostScript vm used here.  Note that since the \
  183.        _NXvmstatus wrap function returns a result, it will implicitly\
  184.        synchronize the given context.  This will make sure that all data in\
  185.        the buffers in either direction has been flushed, and that we can\
  186.        synchronously install our text proc.  */\
  187.     _NXvmstatus(context,vmUsedP);\
  188.     \
  189.     /* Now install our text proc.  We're about to call the dumpwindows\
  190.        operator, which will write out a whole bunch of stuff on the \
  191.        output stream back to us.  We need to install our text proc before\
  192.        we do that, so that when the output comes out we will catch it.\
  193.        Also, we remember the old text proc so we can put it back afterwards. */\
  194.     oldTextProc = context->textProc;\
  195.     DPSSetTextProc(context,_NXMyTextProc);\
  196.     \
  197.     /* Now call the dumpwindows operator, and our text proc catches all\
  198.        the response and puts it in the reponseBuffer. */\
  199.     DPSPrintf(context,"0 currentcontext dumpwindows flush\\n");\
  200.     \
  201.     /* Call DPSWaitContext to be sure we're really done, and all of the\
  202.        responses are really in the responseBuffer.  */\
  203.     DPSWaitContext(context);\
  204.     \
  205.     /* OK, now we've got all the text in responseBuffer.  We can take our\
  206.        text proc back out. */\
  207.     DPSSetTextProc(context,oldTextProc);\
  208.     \
  209.     /* The real work.  We get a line at a time out of reponseBuffer, and\
  210.        look at it to see if it looks like a line generated by the dumpwindows\
  211.        operator.  If so, we parse the memory usage number out of it; if not,\
  212.        we pass it to the old text proc for whatever normal processing occurs. */\
  213.     if (responseBuffer)\
  214.     \{\
  215.     buf = responseBuffer;\
  216.     bufEnd = buf + responseBufCount + 1;\
  217.     *windowBackingP = 0;\
  218.     while(buf < bufEnd) \{\
  219.     \
  220.         /* Find a line.  Null-terminate it. */\
  221.         newBuf = index(buf,'\\n');\
  222.         if (!newBuf) break; /* Every line we want has a newline. */\
  223.         *newBuf = 0;\
  224.         \
  225.         /* See if the line pointed to by buf looks like a dumpwindows line.\
  226.         dumpwindows prints out lines like\
  227.             Layer: (0,448),(672,832) 129024+ bytes (131072)\
  228.         where the "+" is optional. */\
  229.         if (sscanf(buf,"Layer: (%*d,%*d),(%*d,%*d) %d%*c%*s (%d)",\
  230.                 &bytes,&totalBytes) == 2)\
  231.         \{   /* It is one of those lines.  Bump the storage count... */\
  232.         *windowBackingP += totalBytes;\
  233.         \
  234.         /* And echo the line to the dump stream (if any). */\
  235.             if (windowDumpStream) NXPrintf(windowDumpStream,"%s\\n",buf);\
  236.         \}\
  237.         else\
  238.             /* Doesn't look like it's from dumpwindows.  Pass it on to\
  239.            the old text proc (Actually, we should put the carriage\
  240.            return back on before doing this, but that's life). */\
  241.         (*oldTextProc)(context,buf,strlen(buf));\
  242.         buf = newBuf + 1;\
  243.     \} /* while(buf < bufEnd) */\
  244.     \
  245.     /* Free the buffer */\
  246.     free(responseBuffer);\
  247.     \} /* of if (responseBuffer) */\
  248. \
  249.     return(0);\
  250. \} /* NXWindowServerMemory */\
  251. \
  252. /* Implementation of _NXMyTextProc.  All that _NXMyTextProc does is accumulate\
  253.    all the text that comes in on the context while it is active into \
  254.    responseBuffer, realloc'ing it when necessary.  It is left to \
  255.    NXWindowServerMemory to parse the stuff out afterwards.  */\
  256. static void _NXMyTextProc(\
  257.     DPSContext context, \
  258.     char *buf, \
  259.     long unsigned int count)\
  260. \{\
  261.     /* Expand the buffer if necessary */\
  262.     while((count + responseBufCount + 1) > responseBufSize)\
  263.     \{    /* Must expand buffer */\
  264.         if (responseBuffer == NULL)\
  265.     \{\
  266.         responseBuffer = malloc(MINRESPBUFSIZE);\
  267.         responseBufSize = MINRESPBUFSIZE;\
  268.     \}\
  269.     else\
  270.     \{\
  271.         responseBuffer = realloc(responseBuffer,responseBufSize*2);\
  272.         responseBufSize *= 2;\
  273.     \}\
  274.     \}\
  275.     \
  276.     /* Put the new data in the buffer and update the count */\
  277.     bcopy(buf,responseBuffer+responseBufCount,count);\
  278.     responseBufCount += count;\
  279.     \
  280.     /* And null-terminate the buffer (this is used by the main procedure) */\
  281.     *(responseBuffer+responseBufCount) = 0;\
  282. \} /* _NXMyTextProc */\
  283.  
  284. \f3\b0 \
  285.  
  286. \f2\b\fs28 For 2.0
  287. \b0 \
  288. A: There is a new application located under /NextDeveloper/Apps/ProcessMonitor which will allow you to measure and analyze your application's memory usage. In particular, the Display Postscript Inspector shows the amount of backing store and virtual memory used by your Application.  A monitor panel displays these information in graphical form.  Please refer to the documentation under /NextLibrary/Documentation/NextDev/DevTools/04_DevApps/ProcessMonitor.rtfd for further information. You can use the Digital Librarian and search for the keyword ProcessMonitor to bring this document on-line. \
  289.  
  290. \f3\fs24 \
  291.  
  292. \f2\fs28 QA401\
  293. \
  294. Valid for 1.0\
  295. Valid for 2.0 (See differences noted)\
  296. \
  297. \
  298.  
  299.